# app/exceptions/handlers.py

from fastapi import Request, HTTPException
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, HTTP_500_INTERNAL_SERVER_ERROR
from app.config.base_setting import backend_logger, frontend_logger
import traceback
import os
from pydantic import BaseModel
from typing import Optional, List, Dict, Any

ENV = os.getenv("ENV", "development")
logger = backend_logger

class ErrorResponse(BaseModel):
    status: str = "error"
    code: int
    message: str
    details: Optional[List[Dict[str, Any]]] = None
    trace: Optional[str] = None

def format_error(code: int, message: str, trace: str = None, details: List[Dict[str, Any]] = None) -> dict:
    return ErrorResponse(
        code=code,
        message=message,
        trace=trace if ENV == "development" else None,
        details=details
    ).dict(exclude_none=True)

async def http_exception_handler(request: Request, exc: HTTPException):
    logger.warning(f"[HTTPException] {exc.detail} | Path: {request.url.path} | Method: {request.method}")
    return JSONResponse(
        status_code=exc.status_code,
        content=format_error(code=exc.status_code, message=exc.detail)
    )

async def global_exception_handler(request: Request, exc: Exception):
    logger.error(f"Unhandled exception occurred | Path: {request.url.path} | Method: {request.method}", exc_info=True)
    return JSONResponse(
        status_code=HTTP_500_INTERNAL_SERVER_ERROR,
        content=format_error(
            code=HTTP_500_INTERNAL_SERVER_ERROR,
            message="Internal Server Error" if ENV == "production" else str(exc),
            trace=traceback.format_exc()
        )
    )

async def validation_exception_handler(request: Request, exc: RequestValidationError):
    logger.warning(f"[ValidationError] {exc.errors()} | Path: {request.url.path} | Method: {request.method}")
    return JSONResponse(
        status_code=HTTP_422_UNPROCESSABLE_ENTITY,
        content=format_error(
            code=HTTP_422_UNPROCESSABLE_ENTITY,
            message="Validation error",
            details=exc.errors()
        )
    )
